package com.hz.tgb.common;

/**
 * 占位符替换工具类
 * @author hezhao created on 2019/12/4 17:12
 */
public class PlaceholderParse {

    private PlaceholderParse() {
        // 私有工具类
    }

    /**
     * 将字符串text中由openToken和closeToken组成的占位符依次替换为args数组中的值
     * @param openToken 占位符开始
     * @param closeToken 占位符结束
     * @param text 文本
     * @param args 要替换的参数列表
     * @return
     */
    public static String parse(String openToken, String closeToken, String text, Object... args) {
        try {
            if (args == null || args.length <= 0) {
                return text;
            }
            int argsIndex = 0;
            if (text == null || text.isEmpty()) {
                return "";
            }
            char[] src = text.toCharArray();
            int offset = 0;
            // search open token
            int start = text.indexOf(openToken, offset);
            if (start == -1) {
                return text;
            }
            final StringBuilder builder = new StringBuilder();
            StringBuilder expression = null;
            while (start > -1) {
                if (start > 0 && src[start - 1] == '\\') {
                    // this open token is escaped. remove the backslash and continue.
                    builder.append(src, offset, start - offset - 1).append(openToken);
                    offset = start + openToken.length();
                } else {
                    // found open token. let's search close token.
                    if (expression == null) {
                        expression = new StringBuilder();
                    } else {
                        expression.setLength(0);
                    }
                    builder.append(src, offset, start - offset);
                    offset = start + openToken.length();
                    int end = text.indexOf(closeToken, offset);
                    while (end > -1) {
                        if (end > offset && src[end - 1] == '\\') {
                            // this close token is escaped. remove the backslash and continue.
                            expression.append(src, offset, end - offset - 1).append(closeToken);
                            offset = end + closeToken.length();
                            end = text.indexOf(closeToken, offset);
                        } else {
                            expression.append(src, offset, end - offset);
                            offset = end + closeToken.length();
                            break;
                        }
                    }
                    if (end == -1) {
                        // close token was not found.
                        builder.append(src, start, src.length - start);
                        offset = src.length;
                    } else {
                        ///////////////////////////////////////仅仅修改了该else分支下的个别行代码////////////////////////
                        String value = (argsIndex <= args.length - 1) ?
                                (args[argsIndex] == null ? "" : args[argsIndex].toString()) : expression.toString();
                        builder.append(value);
                        offset = end + closeToken.length();
                        argsIndex++;
                        ////////////////////////////////////////////////////////////////////////////////////////////////
                    }
                }
                start = text.indexOf(openToken, offset);
            }
            if (offset < src.length) {
                builder.append(src, offset, src.length - offset);
            }
            return builder.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 替换 ${}
     * @param text 文本
     * @param args 要替换的参数列表
     * @return
     */
    public static String parse$Brace(String text, Object... args) {
        return PlaceholderParse.parse("${", "}", text, args);
    }

    /**
     * 替换 {}
     * @param text 文本
     * @param args 要替换的参数列表
     * @return
     */
    public static String parseBrace(String text, Object... args) {
        return PlaceholderParse.parse("{", "}", text, args);
    }

    /**
     * 替换 []
     * @param text 文本
     * @param args 要替换的参数列表
     * @return
     */
    public static String parseBrackets(String text, Object... args) {
        return PlaceholderParse.parse("[", "]", text, args);
    }

    /**
     * 替换 ()
     * @param text 文本
     * @param args 要替换的参数列表
     * @return
     */
    public static String parseParentheses(String text, Object... args) {
        return PlaceholderParse.parse("(", ")", text, args);
    }

    /**
     * 使用示例
     * @param args
     */
    public static void main(String... args) {
        // {}被转义，不会被替换
        System.out.println(PlaceholderParse.parse("{", "}", "我的名字是\\{},结果是{}，可信度是%{}", "雷锋", true, 100));
        System.out.println(PlaceholderParse.parse$Brace("我的名字是${},结果是${}，可信度是%${}", "雷锋", true, 100));
        System.out.println(PlaceholderParse.parseBrace("我的名字是{},结果是{}，可信度是%{}", "雷锋", true, 100));

        //    输出结果如下：
        //    我的名字是{},结果是true，可信度是%100
        //    我的名字是雷锋,结果是true，可信度是%100
        //    我的名字是雷锋,结果是true，可信度是%100
    }

}